const MyPromise = require("./my-promise")

function resolvePromise1(promise, x, resolve, reject) {
  if (promise === x) {
    return reject(new TypeError('the promise and the return value are same.'))
  }
  if (x instanceof MyPromise) {
    x.then((y) => {
      resolvePromise(promise, y, resolve, reject)
    }, reject)
  } else if (typeof x === 'object' || typeof x === 'function') {
    if (x === null) {
      return resolve(x)
    }
    let then = null
    try {
      then = x.then
    } catch (error) {
      reject(error)
    }
    if (typeof then === 'function') {
      var called = false;
      try {
        then.call(x, (y) => {
          if (called) return;
          called = true;
          resolvePromise(promise, y, resolve, reject)
        }, (r) => {
          if (called) return;
          called = true;
          reject(r)
        })
      } catch (error) {
        if (called) return;
        reject(error)
      }
    } else {
      resolve(x)
    }
  } else {
    resolve(x)
  }
}

function resolvePromise2(promise, x, resolve, reject) {
  if (promise === x) {
    return reject(new TypeError('the promise and the return value are same.'))
  }
  if (x instanceof MyPromise) {
    x.then((y) => {
      resolvePromise(promise, y, resolve, reject)
    }, reject)
  } else if (typeof x === 'object' || typeof x === 'function') {
    if (x === null) {
      return resolve(x)
    }
    let then = null
    try {
      then = x.then
    } catch (error) {
      reject(error)
    }
    if (typeof then === 'function') {
      var called = false;
      try {
        then.call(x, (y) => {
          if (called) return
          called = true;
          resolvePromise(promise, y, resolve, reject)
        }, (r) => {
          if (called) return
          called = true;
          reject(r)
        })
      } catch (error) {
        if (called) return;
        called = true;
        reject(error)
      }
    } else {
      resolve(x)
    }
  } else {
    resolve(x)
  }
}

function resolvePromise3(promise, x, resolve, reject) {
  if (promise === x) {
   return reject(new TypeError('the promise and the return value are same.'))
  }
  if (x instanceof MyPromise) {
    x.then((y) => {
      resolvePromise(promise, y, resolve, reject)
    }, reject)
  } else if (typeof x === 'object' || typeof x === 'function') {
    if (x === null) {
      return resolve(x)
    }
    let then = null
    try {
      then = x.then
    } catch (error) {
      reject(error)
    }
    if (typeof then === 'function') {
      var called = false;
      try {
        then.call(x, (y) => {
          if (called) return;
          called = true;
          resolvePromise(promise, y, resolve, reject)        
        }, (r) => {
          if (called) return;
          called = true;
          reject(r)
        })
      } catch (error) {
        if (called) return;
        called = true;
        reject(error)
      }
    } else {
      resolve(x)
    }
  } else {
    resolve(x)
  }
}

function resolvePromise4(promise, x, resolve, reject) {
  if (promise === x) {
    return reject(new TypeError('the promise and the return value are same.'))
  }
  if (x instanceof MyPromise) {
    x.then((y) => {
      resolvePromise(promise, y, resolve, reject)
    }, reject)
  } else if (typeof x === 'object' || typeof x === 'function') {
    if (x === null) {
      return resolve(x)
    }
    let then = null
    try {
      then = x.then
    } catch (error) {
      reject(error)
    }
    if (typeof then === 'function') {
      let called = false;
      try {
        then.call(x, (y) => {
          if (called) return;
          called = true;
          resolvePromise(promise, y, resolve, reject)
        }, (r) => {
          if (called) return;
          called = true;
          reject(r)
        })
      } catch (error) {
        if (called) return;
        called = true;
        reject(error)
      }
    } else {
      resolve(x)
    }
  } else {
    resolve(x)
  }
}

function resolvePromise5(promise, x, resolve, reject) {
  if (promise === x) {
    return reject(new TypeError('the promise and the return value are same.'))
  }
  if (x instanceof MyPromise) {
    x.then((y) => {
      resolvePromise(promise, y, resolve, reject)
    }, reject)
  } else if (typeof x === 'object' || typeof x === 'function') {
    if (x === null) {
      return resolve(x)
    }
    let then = null
    try {
      then = x.then
    } catch (error) {
      reject(error)
    }
    if (typeof then === 'function') {
      let called = false;
      try {
        then.call(x, (y) => {
          if (called) return;
          called = true;
          resovlePromise(promise, y, resolve, reject)
        }, (r) => {
          if (called) return;
          called = true;
          reject(r)
        })
      } catch (error) {
        if (called) return;
        called = true;
        reject(error)
      }
    } else {
      resolve(x)
    }
  } else {
    resolve(x)
  }
}